(x64 will load a ram image, eg. "the contents of RAM as
in warm start" at startup, if one exists)
Only the RAM is loaded at startup. CPU registers and I/O
are loaded only via 'undump' in the monitor. (That way it
won't keep crashing all the time.)
(1) Includes load address.
(2) Default load address allowed.
5.2 Table of supported file formats.
+ This section shows which emulators and utilities can access which file + formats. This is now a little more complete, thanks to Jouko Valta + (again :> ).
Legend used in table:
x = yes, fully supported, c = convertor provided, - = no, and
empty = unknown.
1. Emulators
x64dsk d64 t64 p00 CBM
x64 0.3.1 x c c c x
PC64 1.10 - x c x c
C64S 1.1A - x x c c
C64Alive 0.9ah - - - - x
MagiC64 - x x
VICE x c c x x
2. Transfer utils
x64dsk d64 t64 p00 CBM Transfer type
Star Commander - x x - x normal/fast
Trans64 x x x x normal
x1541 (old) - - - - x normal
x1541 (new) - - - - x normal
64Copy x x x x x n/a
UnD64 - x - - x n/a
3. Other utils
x64dsk d64 t64 p00 CBM ascii
fvcbm x x x x x -
c1541 x c c x x -
petcat - - - x x x
TOK64 - - - - x x
5.3 Standard data files - internal formats.
This section shows the internal format used by each filetype. Most of it was taken from the compatibility section of the x64 manual, and was provided by Jouko 'Jopi' Valta. That section is based on the information
D64 file contains all sectors as they appear on the 1541 formatted disk.
Each sector is 256 bytes long. Error information (1 byte per sector)
can be added in the end of file.
File types currently supported
174848 bytes = 35 tracks
175531 bytes = 35 tracks + 683 bytes error information
196608 bytes = 40 tracks
197376 bytes = 40 tracks + 768 bytes error information
Track sizes
Tracks, size
1-17 21 sectors * 256 bytes
18-24 19 sectors * 256 bytes
25-30 18 sectors * 256 bytes
31-35 17 sectors * 256 bytes
*36-40* 17 sectors * 256 bytes
Tracks 36-40 are non-standard.
Actual layout for 35 track image
Offset, size, description
0*256, 256 track 1, sector 0
1*256, 256 track 1, sector 1
...
20*256, 256 track 1, sector 20
21*256, 256 track 2, sector 0
...
682*256, 256 track 35, sector 16
683*256, 683 error info (byte per sector in the same order)
Sectors are 256 bytes. Sector 0 is at offset $00000 in the .d64 file. Sector 1 is at offset $00100 in the .d64 file, and so on.
A normal 1541-format disk is divided into 4 'zones' - zone 1 = tracks 1-17 with 21 sectors (numbered 0-20) zone 2 = tracks 18-24 with 19 sectors (numbered 0-18) zone 3 = tracks 25-30 with 18 sectors (numbered 0-17) zone 4 = tracks 31-35 with 17 sectors (numbered 0-16)
The directory lies on track 18. The following info is for
first directory block. Usually the first directory
block is the very next block on the disk
directory blocks:
byte 0 = track of next directory block
byte 1 = sector of next directory block
bytes 2-31 = file entry #1
bytes 32-33 = unused (should be 0)
bytes 34-63 = file entry #2
bytes 64-65 = unused, etc etc
The first byte of a file entry is the type of file ($82 = PRG,
$81 = SEQ, $83 = USR, $80 = DEL, $84 = REL). The next two bytes
point to the track & sector of the first sector of the file.
The next 16 bytes is the filename (padded). The last two bytes
(i.e. bytes 30 & 31) gives the block count of the file (in low
byte/high byte format).
Each file block has 254 bytes of data, unless it is the last block.
The first 2 bytes of each block are the track and sector of the next block.
If the track is zero then this is the last block, and the sector # really tells the number of bytes used out of the 254 possible. The use count is the number of bytes used plus 1--so if the sector # has a $05, then really only $04 bytes were used out of the last block.
The directory is at offset $16500 in the .d64 files. Tracks references start at 1. Sector references start at 0. So if the first 2 bytes of a block are $06 04, the absolute location is at 5 * $1500 + 4 * $100. (5 because that's $06 minus 1. $1500 because at track $06 there are 21 sectors per track, or $1500 bytes. 4 because that is the sector number, and $100 because that's the number of bytes in a sector.)
The disk has a total of 35 tracks. There are 17 trachs with 21 sectors (357 sectors total), 7 tracks with 19 sectors (133 sectors total), 6 tracks with 18 sectors (108 sectors total), and 5 tracks with 17 sectors (85 sectors total). So total sectors per disk (or .d64 image) is 357+133+108+85 = 683 total, or 174,848 bytes total, which is the exact size of the .d64 files.
File: *.t64 tape image Total Size: Varies
------------------------------------------
Offset Bytes Description
0 64 Tape Record:
0 32 Tape description + EOF (for type)
32 2 Tape version: $0100
34 2 Max number of files, in LO/HI
36 2 Number of existing files, in LO/HI
38 2 -
40 24 User description, as displayed in file
menu
64 32*n File Record(s) for each of n files:
+0 1 Slot allocation flag:
00 = free entry
01 = normal tape file
03 = memory snapshot v0.9, uncompressed
02..FF = reserved for memory snapshots
+1 1 File type
+2 2 Start address in C64 memory, in LO/HI
+4 2 End address in C64 memory, in LO/HI
+6 2 -
+8 4 File start address on the image, in
LO/HI
+12 4 -
+16 16 C64 filename
64+32*n ??? File contents.
Wolfgang Lorenz (author of PC64) posted the following in an open letter to Miha Peternel (author of C64S). AFAIK there's been no reply.
There is some ambiguity in the T64 file format. Could you please make a statement if the following assumptions are correct?
Tape Record
Offset, size, description
0, 32 DOS tape description, ASCII charset, contains either
"C64S tape file",13,10,"Demo tape",26,"......" (no
0!) or
"C64S tape image file",0,0,0,0,0,0,0,0,0,0,0,0 or
"C64 tape image file",13,10,0,0,0,0,0,0,0,0,0,0,0
To identify a T64 file, search for the sub-strings
"C64" and "tape".
32, 2 tape version, currently $0100 or $0101
34, 2 number of directory entries, mostly $001E
36, 2 number of used entries (0 for unknown)
38, 2 free
40, 24 user description as displayed in tape menu, CBM
charset, padded with space
File Record
Offset, size, description
0, 1 entry type
0 = free entry
1 = normal tape file
3 = memory snapshot v0.9, uncompressed
2..255 reserved (for memory snapshots...)
1, 1 C64 secondary address, mostly 1
2, 2 start address
4, 2 end address
6, 2 free
8, 4 offset of file contents start within T64 file
12, 4 free
16, 16 C64 file name, CBM charset, padded with space
Example Structure Definitions for C and C++
struct {SHIFT-+}
char acTag[32];
word wVersion;
word wEntries;
word wUsedEntries;
word wReserved;
byte abName[24];
{SHIFT--} T64Header;
struct {SHIFT-+}
byte bType;
byte bSecAdr;
word wStartAdr;
word wEndAdr;
word wReserved;
long lOffset;
long lReserved;
byte abName[16];
{SHIFT--} T64Entry;
File: CBM Files Total Size: Varies
---------------------------------------
Offset Bytes Description
0 2 Load address in LO/HI format.
File: *.p00 file image Total Size: Varies
------------------------------------------
Offset Bytes Description
0 9 String "C64File" terminated by 00.
9 17 Original C64 Filename.
10 1 Record size for REL files.
26 Original file
5.4 Converting between file formats.
Instructions on how to interconvert between all of the formats used
by the various C64 emulators.
One thing to keep in mind is that there are some 'all in one' conversion programs which convert from any format to another; 64Copy is an example.
Formats:
1) .d64 - Disk image used by C64s
2) .t64 - Tape image used by C64s
3) .p00 - image format used by PC64
Conversions:
1) .p00 to .t64
a) Start PC64
b) First get a "Manager" window up
c) Place the cursor on the *.P00 file you want converted
d) Then use "Manager/Export" (ALT-M-E). This will save it as a
*.PRG.
e) Then use MAKETAPE.EXE to make a *.t64 file.
2) .t64 to .p00
Use t64top00.exe, which comes with PC64 and creates p00 copies of
all the t64 files in a directory tree.
6. How to extract the Rom images required by the emulators.
Type in the following files on your C64 and run them to get the rom image files. Then transfer those files onto the machine that you require. See the comp.sys.cbm FAQ section 7 for some details on transfers.
Alternatively, You could get TheA64Package.lha and extract the file called TheA64Package/64Prgs/SaveROMs. This will extract the basic and kernal roms from a C64.
Note that this stuff is only required if your emulator doesn't come with ROMs. Both C64S and PC64 come with ROMS, so don't worry about that.
6.1 C64 roms - Basic, Kernal & Charset.
C64 BASIC ROM extractor:
10 OPEN 5,8,2,"64BASIC,P,W"
20 FOR X=40960 TO 49151:PRINT#2,CHR$(PEEK(X));:NEXT
30 CLOSE 5
C64 KERNEL ROM extractor:
10 OPEN 5,8,2,"64KERNEL,P,W"
20 FOR X=57344 TO 65535:PRINT#2,CHR$(PEEK(X));:NEXT
30 CLOSE 5
C64 BASIC and Kernal ROM extractor:
10 OPEN5,8,5,"0:C64ROM,S,W"
20 FOR X=40960 TO 49151
30 A$=CHR$(PEEK(X))
40 PRINT#5,A$;:NEXT
50 FOR X=57344 TO 65535
60 A$=CHR$(PEEK(X))
70 PRINT#5,A$;:NEXT
90 CLOSE5
C64 Character ROM extractor:
10 POKE 56334,0:POKE 1,51
20 FOR X=16384 TO 20479:POKE X,PEEK(X+36864):NEXT
30 POKE 1,55:POKE 56334,1
40 OPEN 5,8,5,"64CHARGEN,P,W"
50 FOR X=16384 TO 20479
60 PRINT#5,CHR$(PEEK(X));:NEXT
70 CLOSE 5
6.2 VIC20 roms - Basic, Kernel & Charset.
VIC20 BASIC ROM extractor:
10 OPEN 5,8,2,"V20BASIC,P,W"
20 FOR X=49152 TO 57343:PRINT#5,CHR$(PEEK(X));:NEXT
30 CLOSE 5
VIC20 KERNEL ROM extractor:
10 OPEN 5,8,2,"V20KERNEL,P,W"
20 FOR X=57344 TO 65535:PRINT#5,CHR$(PEEK(X));:NEXT
30 CLOSE 5
VIC20 Character ROM extractor:
10 OPEN 5,8,2,"V20CHARGEN,P,W"
20 FOR X=32768 TO 36863:PRINT#5,CHR$(PEEK(X));:NEXT
30 CLOSE 5
6.3 1541 rom.
C1541 ROM extractor:
Extract area $C000-$FFFF
100 B=16384:I=B
110 OPEN 15,8,15
120 FOR H=192 TO 255:PRINT H;
130 FOR L=0 TO 255
140 PRINT#15,"M-R";CHR$(L);CHR$(H)
150 GET#15,A$
160 Z=FRE(0)
170 POKE I,ASC(A$+CHR$(0))
180 I=I+1:NEXT L
190 NEXT H
200 CLOSE 15
210 OPEN 5,8,5,"0:C1541ROM,P,W"
220 FOR X=B TO I-1:PRINT#5,CHR$(PEEK(X));:NEXT
230 CLOSE 5
7. Other information.
---------------------
7.1 Newsgroups worth reading.
If you want to ask a question about an emulator or read what other
people are saying, then I recommend that you read comp.emulators.cbm
Another good group to read for general info about Commodore 8bit machines is comp.sys.cbm.
7.2 Emulator benchmarks.
Some people are interested in the relative speed of the emulators with respect to the actual machine it's emulating. So far, only the following simple test program has been used in benchmarking emulators. More tests and more machines are needed!
Benchmark test #1.
10 a = ti
20 print "[clr/home]"
30 for i = 1 to 1000
40 print "[up][up]"; i ; i * i
50 next
60 print "[down][down] time = "; ti -a
Results:
"Machine" "Config" "Software" "Score"
C64 PAL CBM BASIC 1508
C128 64 mode CBM BASIC 1590
C128 40 col CBM BASIC 2226
C128 40 col fast CBM BASIC 1071 (1)
C128 80 col CBM BASIC 4072
C128 80 col fast CBM BASIC 2062
Sun SPARC IPC 8Mb RAM x64-0.2.2 1452 (2)
Osborne 486 DX2/50 16Mb RAM c64hercules 286
Osborne 486 DX2/50 16Mb RAM c64sally 234
Osborne 486 DX2/50 16Mb RAM c64s10cd 1486
Osborne 486 DX2/50 16Mb RAM c64neu 2985
Osborne 486 DX2/50 16Mb RAM c64alive --- (3)
Amiga 3000/25 6Mb RAM A64v2 788
Amiga 4000/060-50 20Mb RAM Frodo v1.5 1463
Amiga 4000/060-50 20Mb RAM Frodo-II v0.1 1508
Atari 1040 STfm Hi-res c64.tos 3567 (58 s real)
Atari 1040 STfm Low-res c64.tos 3624 (58 s real)
Notes:
(1) Screen automatically blanked during test.
(2) "ti" clock doesn't necessarilly keep real time in x64. In x64
the ti clock is relative to the virtual speed, not the wall
clock time.
(3) c64alive wouldn't run on the test machine. Doh.
7.3 Emulator detection.
Writers of software on the C64 or emulators may wish to know whether the "machine" their code is executing on is a real C64, or not. A small BASIC program was written by Wolfgang Lorenz, and posted by Paul David Doherty, which tests this.
Critical addresses for the PIA expansion
The critical addresses of the device are 57216--57343 ($DF80--
$DFFF).
There is the PIA chip to which you POKE the values to switch memory
blocks. The PIA does not have 128 registers, as one might think.
There are sixteen copies of its 4 addresses in that memory area. For
instance, the addresses 57216, 57284, 57288 and 57340 are equivalent
to each other.
Here's a small CBM-BASIC program by Wolfgang Lorenz which tests
whether it is running on a real C-64 or on an emulator. It also
contains a suggested method for emulators to allow other programs
to detect them. This detection method is already implemented
in the PC64 and C64S emulators; it would be nice if other emulators
(A64, MAC64, C64ALIVE, X64) would adhere to it too.
100 rem *** where am i? *** 105 rem ------------------------------- 110 rem this is the recommended method
115 rem how to detect a c64 emulator,
120 rem e.g. for disabling fast loaders
125 rem
130 rem - the byte at $dfff changes
135 rem between $55 and $aa
140 rem - the byte at $dffe contains
145 rem the manufacturer code letter:
150 rem a = c64alive 152 rem f = frodo
161 rem p = personal c64
175 rem s = c64 software emulator
180 rem x = x64
185 rem - the word at $dffc contains
190 rem the emulator version number,
195 rem e.g. $0120 for version 1.2
200 rem - the bytes from $dfa0 contain
205 rem a copyright string with
210 rem emulator name and version,
215 rem $0d, copyright and $00.
240 :
245 print:x=57343:if peek(x)<>85 then if peek(x)<>85 then 360
410 x=57087:if peek(x)+peek(x)+peek(x)<>0 then 435
415 print "c64alive"
420 print "(c)1993-94 f.littmann developments"
425 end
430 :
435 print "this is an original c64 or c128"
You can distinquish a real C128 from C64 by testing the VDC status register at $D600/$D601: If the value written to $D601 remains intact, its a C128 in either mode, otherwise a real C64. There is no way (or need) to tell C64 from C64c though.
7.4 Other sources of information.
There are a number of WWW addresses that may be of interest...